from typing import Dict, List, Optional, Any, Union
from enum import Enum
from pydantic import BaseModel, Field, validator

class ResponseMode(str, Enum):
    """响应模式枚举"""
    BLOCKING = "blocking"  # 阻塞模式
    STREAMING = "streaming"  # 流式模式

class FileObject(BaseModel):
    """文件对象模型"""
    type: str = Field(..., description="文件类型，如image、document、audio、video或custom")
    transfer_method: str = Field(..., description="传递方式：remote_url或local_file")
    url: Optional[str] = Field(None, description="文件URL，当transfer_method为remote_url时使用")
    upload_file_id: Optional[str] = Field(None, description="上传文件ID，当transfer_method为local_file时使用")
    id: Optional[str] = Field(None, description="文件ID，由系统生成")

class ChatRequest(BaseModel):
    """聊天请求模型"""
    query: str = Field(..., description="用户的提问或指令内容")
    user: str = Field(..., description="用户的唯一标识")
    inputs: Optional[Dict[str, Any]] = Field({}, description="变量输入，用于填充应用中定义的变量")
    response_mode: ResponseMode = Field(ResponseMode.STREAMING, description="响应模式：blocking或streaming")
    conversation_id: Optional[str] = Field(None, description="会话ID，用于关联到特定会话")
    files: Optional[List[FileObject]] = Field(None, description="消息关联的文件列表")
    auto_generate_name: Optional[bool] = Field(True, description="是否自动生成标题，默认为true")
    
    @validator('query')
    def query_not_empty(cls, v):
        """验证查询内容不为空"""
        if not v or not v.strip():
            raise ValueError("查询内容不能为空")
        return v.strip()

class MessageAgentThought(BaseModel):
    """代理思考过程模型"""
    agent_name: str = Field(..., description="代理名称")
    thought: str = Field(..., description="思考内容")

class MessageChunk(BaseModel):
    """消息块模型，用于流式响应"""
    id: str = Field(..., description="消息ID")
    task_id: str = Field(..., description="任务ID")
    answer: str = Field("", description="当前累积的回答内容")
    created_at: int = Field(..., description="创建时间戳")
    conversation_id: str = Field(..., description="会话ID")
    agent_thoughts: Optional[List[MessageAgentThought]] = Field(None, description="代理思考过程")
    metadata: Optional[Dict[str, Any]] = Field(None, description="元数据")
    
    class Config:
        """Pydantic配置"""
        json_encoders = {
            # 自定义编码器（如果需要）
        }

class MessageFeedback(BaseModel):
    """消息反馈模型"""
    rating: Optional[str] = Field(..., description="评分：like、dislike或null（撤销点赞）")
    user: str = Field(..., description="用户ID")
    content: Optional[str] = Field(None, description="反馈内容")

class CompleteMessage(MessageChunk):
    """完整消息模型，继承消息块并添加更多字段"""
    message_files: Optional[List[FileObject]] = Field(None, description="消息相关文件")
    retriever_resources: Optional[List[Dict[str, Any]]] = Field(None, description="检索器资源")
    
    class Config:
        """Pydantic配置"""
        json_encoders = {
            # 自定义编码器（如果需要）
        }

class StopTaskRequest(BaseModel):
    """停止任务请求模型"""
    user: str = Field(..., description="用户ID")

class ChatStopResponse(BaseModel):
    """停止任务响应模型"""
    result: str = Field(..., description="操作结果")

class ChatResponse(BaseModel):
    """聊天响应模型（非流式）"""
    id: str = Field(..., description="消息ID")
    task_id: str = Field(..., description="任务ID")
    answer: str = Field(..., description="完整的回答内容")
    created_at: int = Field(..., description="创建时间戳")
    conversation_id: str = Field(..., description="会话ID")
    metadata: Optional[Dict[str, Any]] = Field(None, description="元数据")
    agent_thoughts: Optional[List[MessageAgentThought]] = Field(None, description="代理思考过程")
    message_files: Optional[List[FileObject]] = Field(None, description="消息相关文件")
    retriever_resources: Optional[List[Dict[str, Any]]] = Field(None, description="检索器资源")

# 流式响应事件类型
class StreamEventType(str, Enum):
    """流式事件类型枚举"""
    MESSAGE = "message"
    ERROR = "error"
    META = "meta"
    PING = "ping"

class StreamResponse(BaseModel):
    """流式响应模型"""
    event: StreamEventType = Field(..., description="事件类型")
    data: Union[MessageChunk, Dict[str, Any], str] = Field(..., description="事件数据")
    
    class Config:
        """Pydantic配置"""
        arbitrary_types_allowed = True

class SuggestedQuestionsResponse(BaseModel):
    """建议问题响应模型"""
    result: str = Field("success", description="操作结果")
    data: List[str] = Field(..., description="建议问题列表")

class MessageHistoryItem(BaseModel):
    """消息历史项模型"""
    id: str = Field(..., description="消息ID")
    conversation_id: str = Field(..., description="会话ID")
    inputs: Dict[str, Any] = Field({}, description="用户输入参数")
    query: str = Field(..., description="用户输入/提问内容")
    answer: str = Field(..., description="回答消息内容")
    message_files: List[FileObject] = Field([], description="消息文件")
    feedback: Optional[Dict[str, Any]] = Field(None, description="反馈信息")
    retriever_resources: Optional[List[Dict[str, Any]]] = Field(None, description="引用和归属分段列表")
    created_at: int = Field(..., description="创建时间戳")

class MessageHistoryResponse(BaseModel):
    """消息历史响应模型"""
    data: List[MessageHistoryItem] = Field(..., description="消息列表")
    has_more: bool = Field(..., description="是否有更多消息")
    limit: int = Field(..., description="返回条数")
